package com.sojson.config.datasource;

import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

import com.sojson.util.ArrayUtil;
import com.sojson.util.StringUtil;
import com.sojson.util.threadLocal.CustomThreadLocalUtil;

import lombok.extern.slf4j.Slf4j;

/**
 * 动态数据源
 * 
 * @author liu
 * @date 2021-07-04
 */
@Slf4j
public class CustomSqlSessionFactoryDataSource extends AbstractRoutingDataSource {

    /** 数据源名称集合 */
    private Map<Object, List<Object>> dataSourceNames;

    /**
     * 初始化数据源池
     * 
     * @param dataSourceName    默认数据源名称
     * @param dataSourcePool    数据源池
     * @param dataSourceNames   数据源名称集合
     */
    public CustomSqlSessionFactoryDataSource(Object dataSourceName, Map<Object, Object> dataSourcePool,
        Map<Object, List<Object>> dataSourceNames) {
        // 保存所有数据源的名称
        this.dataSourceNames = dataSourceNames;
        // 设置数据源池
        super.setTargetDataSources(dataSourcePool);

        // 输入日志
        log.info("设置默认的SqlSessionFactory数据源池集合:[");
        Set<Entry<Object, List<Object>>> entrySet = dataSourceNames.entrySet();
        for (Entry<Object, List<Object>> entry : entrySet) {
            log.info("    " + entry.getKey() + "的数据源池:[");
            List<Object> value = entry.getValue();
            int size = value.size();
            for (int i = 0; i < size; i++) {
                Object object = value.get(i);
                if (i == size - 1) {
                    log.info("        " + object.toString());
                } else {
                    log.info("        " + object + ",");
                }
            }
            log.info("    ]");
        }
        log.info("]");
        // 设置默认数据源
        super.setDefaultTargetDataSource(dataSourcePool.get(dataSourceName));
        log.info("默认的SqlSessionFactory的默认数据源为: {}", dataSourceName);
        // 数据源初始化
        super.afterPropertiesSet();
        log.info("默认的SqlSessionFactory所有数据源已初始化!");
    }

    /**
     * 获取要使用的数据源
     */
    @Override
    protected Object determineCurrentLookupKey() {
        // 从缓存获取数据源
        Object obj = CustomThreadLocalUtil.getDataSource();
        if (StringUtil.isNotBlankObject(obj)) {
            return obj;
        }

        // 获取数据源类型名称,是否有选择类型,如果没有选择就使用默认的
        Object dataSourceType = CustomThreadLocalUtil.getDataSourceType();
        // 如果没有选择数据源就设置为默认数据源集合
        if (StringUtil.isBlankObject(dataSourceType)) {
            return null;
        }

        // 如果选择了数据源就从这个数据源集合中抽一个数据源
        List<Object> list = dataSourceNames.get(dataSourceType);

        // 从此类型的数据源集合中随机获取一个并缓存
        obj = ArrayUtil.getRandom(list);
        // 缓存数据源
        CustomThreadLocalUtil.setDataSource(obj);
        return obj;
    }

}